package com.royal.lr.netty;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.MemoryAttribute;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class RequestParser {

    private static final Logger logger = LogManager.getLogger(RequestParser.class);

    private FullHttpRequest request;
    /**
     * 构造一个Http请求参数解析器
     * @param request
     */
    public RequestParser(FullHttpRequest request) {
        this.request = request;
    }

    /**
     * 解析请求参数
     * @return 包含所有请求参数的键值对, 如果没有参数, 则返回空Map
     *
     * @throws Exception
     */
    public Map<String, Object> parse() throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<String, Object>();

        HttpMethod method = request.method();

        if (method == HttpMethod.GET) {
            // 处理get请求
            QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
            Map<String, List<String>> paramList = decoder.parameters();
            for (Map.Entry<String, List<String>> entry : paramList.entrySet()) {
                params.put(entry.getKey(), entry.getValue().get(0));
            }
        }else if(method == HttpMethod.POST){
            String strContentType = request.headers().get("Content-Type").trim();
            logger.info("Content-Type:"+strContentType);
            logger.info(strContentType.contains("application/json"));
            if (strContentType.contains("x-www-form-urlencoded")) {
                params  = getFormParams(request);
            } else if (strContentType.contains("application/json")) {
                    params = getJSONParams(request);
            }
        }
        return params;
    }


    /*
     * 解析from表单数据（Content-Type = x-www-form-urlencoded）
     */
    private Map<String, Object> getFormParams(HttpRequest fullHttpRequest) {
        Map<String, Object> params = new HashMap<String, Object>();

        HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(new DefaultHttpDataFactory(false), fullHttpRequest);
        List<InterfaceHttpData> postData = decoder.getBodyHttpDatas();

        for (InterfaceHttpData data : postData) {
            if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                MemoryAttribute attribute = (MemoryAttribute) data;
                params.put(attribute.getName(), attribute.getValue());
            }
        }

        return params;
    }

    /*
     * 解析json数据（Content-Type = application/json）
     */
    private Map<String, Object> getJSONParams(FullHttpRequest httpRequest) throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<String, Object>();

        ByteBuf content = httpRequest.content();
        byte[] reqContent = new byte[content.readableBytes()];
        content.readBytes(reqContent);
        String strContent = new String(reqContent, "UTF-8");
        logger.info("strContent:"+strContent);
        try {
            JSONObject jsonParams = JSON.parseObject(strContent);
            for (Object key : jsonParams.keySet()) {
                params.put(key.toString(), jsonParams.get(key));
            }
        }catch (Exception e){
            logger.error("error:",e);
        }

        return params;
    }

}
